package com.dashu.core.service;

import com.dashu.base.enums.ReplRyCode;
import com.dashu.base.utils.http.token.TokenTools;
import com.dashu.core.dto.UserDTO;
import com.dashu.core.result.PageEnty;
import com.dashu.base.utils.CopyUtil;
import com.dashu.base.utils.UIDUtil;
import com.dashu.base.utils.VerificationUtil;
import com.dashu.core.dto.PermissionDTO;
import com.dashu.core.dto.PermissionListDTO;
import com.dashu.core.handler.VerificationException;
import com.dashu.core.model.PermissionRule;
import com.dashu.core.model.QPermissionRule;
import com.dashu.core.result.ResultBean;
import com.dashu.core.vo.PermissionListVO;
import com.dashu.core.vo.PermissionVO;
import com.dashu.core.vo.UpdateEntityVO;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.FlushModeType;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class PermissionService extends DataService {
    @Autowired
    private UserService userService;

    @Transactional
    public PermissionDTO add(PermissionVO permissionVO) {
        PermissionRule permissionRule = CopyUtil.copyEnty(permissionVO, PermissionRule.class);
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            permissionRule.setId(UIDUtil.nextId());
            permissionRule.setCreateUser(userId);
            permissionRule.setCreateTime(System.currentTimeMillis());
            entityManager.persist(permissionRule);
//            entityManager.flush();
            entityManager.setFlushMode(FlushModeType.AUTO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VerificationException(ReplRyCode.DATA_NOT_INVALID, ReplRyCode.DATA_NOT_INVALID.getMessage());
        }
        PermissionDTO permissionDTO = CopyUtil.copyEnty(permissionRule, PermissionDTO.class);
        return permissionDTO;

    }

    @Transactional
    public boolean deleteByPermissionRuleId(long PermissionRuleId) {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qPermissionRule.id.eq(PermissionRuleId));
        PermissionRule permissionRule;
        queryFactory.select();
        permissionRule = queryFactory
                .select(qPermissionRule)
                .from(qPermissionRule)
                .where(booleanBuilder.getValue()).fetchOne();
        if (permissionRule == null)
            throw new VerificationException(ReplRyCode.PERMISSION_NOT_DATA, ReplRyCode.PERMISSION_NOT_DATA.getMessage());
        entityManager.remove(permissionRule);
//            entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        return true;

    }

    @Transactional
    public PermissionDTO updataByPermissionRuleId(UpdateEntityVO<PermissionVO> updatePermissionVO) throws Exception {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        PermissionVO permissionVO = updatePermissionVO.getEntityVO();
        PermissionDTO isPermission = existByPermissionRuleName(permissionVO.getRuleName());
        if (isPermission != null) {
            if(isPermission.getId()!=updatePermissionVO.getId())
            throw new VerificationException(ReplRyCode.EXIST_PERMISSION, ReplRyCode.EXIST_PERMISSION.getMessage());
        }
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qPermissionRule.id.eq(updatePermissionVO.getId()));
        PermissionRule permissionRule;
        try {
            permissionRule = queryFactory
                    .select(qPermissionRule)
                    .from(qPermissionRule)
                    .where(booleanBuilder.getValue()).fetchOne();
            if (permissionVO == null)
                return CopyUtil.copyEnty(permissionRule, PermissionDTO.class);
            if (permissionVO.getRuleDevice() != null) ;
            permissionRule.setRuleDevice(permissionVO.getRuleDevice());
            if (permissionVO.getRulePersonnel() != null) ;
            permissionRule.setRulePersonnel(permissionVO.getRulePersonnel());
            if (permissionVO.getRuleTeaching() != null) ;
            permissionRule.setRuleTeaching(permissionVO.getRuleTeaching());
            if (permissionVO.getRuleSystem() != null) ;
            permissionRule.setRuleSystem(permissionVO.getRuleSystem());
            if (permissionVO.getRuleAttendance() != null) ;
            permissionRule.setRuleAttendance(permissionVO.getRuleAttendance());
            if (permissionVO.getRuleName() != null) ;
            permissionRule.setRuleName(permissionVO.getRuleName());
            if (permissionVO.getRuleType() != 0) ;
            permissionRule.setRuleType(permissionVO.getRuleType());
            permissionRule.setUpdateUser(userId);
            permissionRule.setUpdateTime(new Date().getTime());
            permissionRule = entityManager.merge(permissionRule);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
//        entityManager.flush();
        entityManager.setFlushMode(FlushModeType.AUTO);
        userService.findBypId(permissionRule.getId()).forEach( us ->{
            TokenTools.createToken(VerificationUtil.getRequest(), us.getUserName(), String.valueOf(us.getId()));
        });
        PermissionDTO permissionDTO = CopyUtil.copyEnty(permissionRule, PermissionDTO.class);
        return permissionDTO;

    }

    public List<PermissionDTO> findByBaseId(PageEnty<Long> baseVo) {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qPermissionRule.baseId.eq(baseVo.getBaseId()));
        List<PermissionRule> permissionRules = queryFactory
                .select(qPermissionRule)
                .from(qPermissionRule)
                .where(booleanBuilder.getValue())
                .fetch();
        List<PermissionDTO> recycleDTOS = CopyUtil.copyList(permissionRules, PermissionDTO.class);
        return recycleDTOS;

    }

    public PermissionDTO findByPermissionRuleId(long PermissionRuleId) {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qPermissionRule.id.eq(PermissionRuleId));
        PermissionRule permissionRule = queryFactory
                .select(qPermissionRule)
                .from(qPermissionRule)
                .where(booleanBuilder.getValue()).fetchOne();
        if (permissionRule == null)
            throw new VerificationException(ReplRyCode.PERMISSION_NOT_DATA, ReplRyCode.PERMISSION_NOT_DATA.getMessage());
        PermissionDTO permissionDTO = CopyUtil.copyEnty(permissionRule, PermissionDTO.class);
        return permissionDTO;

    }

    public PermissionDTO existByPermissionRuleName(String PermissionRuleName) throws Exception {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        long userId = Long.parseLong(VerificationUtil.getUserId());
        booleanBuilder.and(qPermissionRule.ruleName.eq(PermissionRuleName));
        booleanBuilder.and(qPermissionRule.createUser.eq(userId));
        PermissionRule permissionRule = queryFactory
                .select(qPermissionRule)
                .from(qPermissionRule)
                .where(booleanBuilder.getValue())
                .fetchFirst();
        PermissionDTO permissionDTO = CopyUtil.copyEnty(permissionRule, PermissionDTO.class);
        return permissionDTO;

    }

    public PermissionDTO PermissionRuleName(String permissionRuleName) {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qPermissionRule.ruleName.eq(permissionRuleName));
        PermissionRule permissionRule = queryFactory
                .select(qPermissionRule)
                .from(qPermissionRule)
                .where(booleanBuilder.getValue()).fetchOne();
        if (permissionRule == null)
            throw new VerificationException(ReplRyCode.PERMISSION_NOT_DATA, ReplRyCode.PERMISSION_NOT_DATA.getMessage());
        PermissionDTO permissionDTO = CopyUtil.copyEnty(permissionRule, PermissionDTO.class);
        return permissionDTO;

    }

    public long permissionCount(PageEnty<PermissionListVO> permissionListPageEntyVO) throws Exception {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        long baseId = permissionListPageEntyVO.getBaseId() == 0 ? userId : permissionListPageEntyVO.getBaseId();
        PermissionListVO permissionListVO = permissionListPageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
//        if (admin != baseId)
        booleanBuilder.and(qPermissionRule.baseId.eq(baseId));
        if (!StringUtils.isEmpty(permissionListVO.getRuleName()))
            booleanBuilder.and(qPermissionRule.ruleName.eq(permissionListVO.getRuleName()));

        long count = queryFactory
                .select(qPermissionRule.count())
                .from(qPermissionRule)
                .where(booleanBuilder.getValue())
                .fetchCount();

        return count;

    }

    public List<PermissionListDTO> findByPermissionList(PageEnty<PermissionListVO> permissionListPageEntyVO) throws Exception {
        QPermissionRule qPermissionRule = QPermissionRule.permissionRule;
        long userId = Long.parseLong(VerificationUtil.getUserId());
        long baseId = permissionListPageEntyVO.getBaseId() == 0 ? userId : permissionListPageEntyVO.getBaseId();
        PermissionListVO permissionListVO = permissionListPageEntyVO.getVo();
        BooleanBuilder booleanBuilder = new BooleanBuilder();
//        if (admin != baseId)
        booleanBuilder.and(qPermissionRule.baseId.eq(baseId));
        if (!StringUtils.isEmpty(permissionListVO.getRuleName()))
            booleanBuilder.and(qPermissionRule.ruleName.like("%" + permissionListVO.getRuleName() + "%"));
        List<PermissionRule> permissionRules = queryFactory
                .select(qPermissionRule)
                .from(qPermissionRule)
                .where(booleanBuilder.getValue())
                .offset((permissionListPageEntyVO.getPage() - 1) * permissionListPageEntyVO.getNum())
                .limit(permissionListPageEntyVO.getNum())
                .orderBy(qPermissionRule.createTime.desc())
                .fetch();
        List<PermissionListDTO> permissionListDTOS = CopyUtil.copyList(permissionRules, PermissionListDTO.class);
//        permissionListDTOS.stream().forEach(pd -> {
//            UserDTO userDTO = userService.findByUserId(pd.getCreateUser());
//            pd.setBaseName(userDTO.getNickname());
//        });
        return permissionListDTOS;

    }


}
